package com.ttg.service;

//~--- non-JDK imports --------------------------------------------------------

import com.alibaba.fastjson.JSON;
import com.ttg.contants.TestContants;
import com.ttg.security.RSA;
import com.ttg.utils.Assert;
import com.ttg.utils.Bytes;
import com.ttg.utils.DataUtil;
import com.ttg.utils.connection.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

//~--- JDK imports ------------------------------------------------------------

//~--- classes ----------------------------------------------------------------

/**
 * Class HttpBaseService
 * Description
 * Create 2015-11-26 17:09:06
 * @author Ardy    
 */
public class HttpBaseService {

    /** 
     * Field logger
     * Description 
     */
    private static final Logger logger = LoggerFactory.getLogger(HttpBaseService.class);

    /**
     * Field charset
     * Description
     */
    private final String charset = "UTF-8";

    /**
     * Field method
     * Description
     */
    private final String method = "post";

    /**
     * Field language
     * Description
     */
    private String language = "zh_CN";

    /**
     * Field responseTimeoutSeconds
     * Description
     */
    private Integer responseTimeoutSeconds = null;

    /**
     * Field connectionTimeoutSeconds
     * Description
     */
    private Integer connectionTimeoutSeconds = null;

    /**
     * Method getMethod
     * Description
     * @return  String
     */
    public String getMethod() {
        return method;
    }

    /**
     * Method setResponseTimeoutSeconds
     * Description
     *
     * @param responseTimeoutSeconds Integer
     *
     * @throws TTGHttpClientException
     */
    public void setResponseTimeoutSeconds(Integer responseTimeoutSeconds) throws TTGHttpClientException {
        if (this.isTimeMoreThanZeroMinAndLessThan10MinsOfResponseTimeout(responseTimeoutSeconds)) {
            this.responseTimeoutSeconds = responseTimeoutSeconds;
        } else {
            throw new TTGHttpClientException("设置的交易超时响应时间要大于0小于10分钟", null);
        }
    }

    /**
     * Method setConnectionTimeoutSeconds
     * Description
     *
     * @param connectionTimeoutSeconds Integer
     *
     * @throws TTGHttpClientException
     */
    public void setConnectionTimeoutSeconds(Integer connectionTimeoutSeconds) throws TTGHttpClientException {
        if (this.isTimeMoreThanZeroMinAndLessThan2MinsOfConnectionTimeout(connectionTimeoutSeconds)) {
            this.connectionTimeoutSeconds = connectionTimeoutSeconds;
        } else {
            throw new TTGHttpClientException("设置的交易连接超时时间要大于0小于2分钟", null);
        }
    }

    /**
     * Method sendNonbatchInfo
     * Description 发送HTTP请求，返回的为JSON信息
     *
     * @param url String 请求的URI
     * @param parameters Map<String,String> 请求的参数
     * @param retryCount int 重连的次数
     * @param method String
     * @param requestSentRetryEnabled boolean 是否发送重连
     * @param resultType Class<T> 返回后转化的实体类型
     * @param <T> $paramType$
     *
     * @return T
     *
     * @throws TTGHttpClientException
     */
    protected <T> T sendNonbatchInfo(String url, Map<String, String> parameters, int retryCount, String method,
                                     boolean requestSentRetryEnabled, Class<T> resultType)
            throws TTGHttpClientException {
        logger.debug("组装非批量业务请求参数:[{}]", parameters);

        if (( parameters != null ) && ( parameters.size() != 0 )) {
            Assert.notNull(resultType, "resultType不能为空");

            try {
                HttpRequest e = new HttpRequest(url, charset);

                e.setLanguage(this.language);

                if (method != null) {
                    e.setMethod(method);
                }

                this.setTimeoutOfHttpRequest(e);
                e.setParameters(parameters);

                String stringResult = HttpClient.get().requestWithStringResult(e, retryCount, requestSentRetryEnabled);

                logger.debug("接收到的返回信息为：{}", stringResult);

                T result = JSON.parseObject(stringResult, resultType);

                return result;
            } catch (Throwable var9) {
                if (var9 instanceof TTGHttpClientException) {
                    throw(TTGHttpClientException) var9;
                } else {
                    throw new TTGHttpClientException(var9);
                }
            }
        } else {
            throw new IllegalArgumentException("parameters不能为空");
        }
    }



    protected <T> T sendBatchInfo(String url, Map<String, String> parameters, List<HttpUploadFile> uploadFiles, int retryCount, boolean requestSentRetryEnabled, Class<T> resultType) throws TTGHttpClientException {
        logger.debug ("组装批量业务请求参数:[{}]", parameters);
        if(parameters != null && parameters.size() != 0) {
            if(uploadFiles != null && uploadFiles.size() != 0) {
                Assert.notNull(resultType, "resultType不能为空");

                try {

                    Map e = this.signParameters(parameters, uploadFiles);
                    //todo
                    //压缩文件，减少网络时间
                    //List uploadZipFiles = this.doCompress(uploadFiles);
                    UploadHttpRequest req = new UploadHttpRequest(url, charset, uploadFiles);
                    req.setParameters(e);
                    req.setLanguage(this.language);
                    req.setMethod("POST");
                    this.setTimeoutOfHttpRequest(req);
                    String stringResult = HttpClient.get().requestWithStringResult(req, retryCount, requestSentRetryEnabled);
                    T result = JSON.parseObject(stringResult, resultType);
                    return result;
                } catch (Throwable var11) {
                    if(var11 instanceof TTGHttpClientException) {
                        throw (TTGHttpClientException)var11;
                    } else {
                        throw new TTGHttpClientException(var11);
                    }
                }
            } else {
                throw new IllegalArgumentException("uploadFiles不能为空");
            }
        } else {
            throw new IllegalArgumentException("parameters不能为空");
        }
    }


    private Map<String, String> signParameters(Map<String, String> originalParameters, List<HttpUploadFile> uploadFiles) throws Exception {
        Map parameters = HttpClientUtils.paramFilter (originalParameters, "signatureAlgorithm", "signatureInfo");
        this.attachFileDigest(parameters, uploadFiles);
        String prestr = HttpClientUtils.createLinkString (parameters);
        Charset encoding = Charset.forName("UTF-8");
        logger.debug ("加签的字符串：{}",prestr);
        //String encodeBase64String = this.signProvider.signByPri(prestr.getBytes("UTF-8"), encoding);
        String sign= RSA.signByPri (prestr, TestContants.PRIVATE_KEY, TestContants.CHARSET_UTF8);

        parameters.put ("signatureInfo", sign);
        parameters.put("signatureAlgorithm", TestContants.SIGNATUREALGORITHM);
        return parameters;
    }

    private void attachFileDigest(Map<String, String> parameters, List<HttpUploadFile> uploadFiles) throws Exception {
        if(uploadFiles != null && uploadFiles.size() > 0) {
            StringBuilder sb = new StringBuilder();
            Iterator i$ = uploadFiles.iterator();

            while(i$.hasNext()) {
                HttpUploadFile file = (HttpUploadFile)i$.next();
                String fileMD5Base64;
                if(file.getContent() != null) {
                    fileMD5Base64 = Bytes.getMD5(file.getContent(), "UTF-8");
                    sb.append(fileMD5Base64);
                } else {
                    fileMD5Base64 = Bytes.getFileMD5Base64(file.getFile(), "UTF-8");
                    sb.append(fileMD5Base64);
                }
            }

            parameters.put("fileDigest", sb.toString());
        }

    }
    /**
     * Method sendHttpReqInfo
     * Description 发送HTTP请求，返回的为页面信息
     *
     * @param method String
     * @param   <T> $paramType$
     * @param    url String
     * @param    parameters Map<String,String>
     * @param    retryCount int
     * @param    requestSentRetryEnabled boolean
     * @param    resultType Class<T>
     * @return  T
     *
     * @throws TTGHttpClientException
     */
    protected <T> String sendHttpReqInfo(String url, Map<String, String> parameters, int retryCount, String method,String charset,
            boolean requestSentRetryEnabled, Class<T> resultType)
            throws TTGHttpClientException {
        logger.debug("组装非批量业务请求参数:[{}]", parameters);

        if (( parameters != null ) && ( parameters.size() != 0 )) {
            Assert.notNull(resultType, "resultType不能为空");

            try {
                HttpRequest e = new HttpRequest(url, DataUtil.isEmpty (charset)?this.charset:charset);

                e.setLanguage(this.language);
                e.setMethod(method);
                this.setTimeoutOfHttpRequest(e);
                e.setParameters(parameters);

                String stringResult = HttpClient.get().requestWithStringResult(e, retryCount, requestSentRetryEnabled);

                logger.debug("接收到的返回信息为：{}", stringResult);

                return stringResult;
            } catch (Throwable var9) {
                if (var9 instanceof TTGHttpClientException) {
                    throw(TTGHttpClientException) var9;
                } else {
                    throw new TTGHttpClientException(var9);
                }
            }
        } else {
            throw new IllegalArgumentException("parameters不能为空");
        }
    }

    /**
     * Method setTimeoutOfHttpRequest
     * Description
     *
     * @param req HttpRequest
     */
    private void setTimeoutOfHttpRequest(HttpRequest req) {
        if (null != this.connectionTimeoutSeconds) {
            req.setConnectionTimeout(this.connectionTimeoutSeconds.intValue() * 1000);
        }

        if (null != this.responseTimeoutSeconds) {
            req.setTimeout(this.responseTimeoutSeconds.intValue() * 1000);
        }
    }

    /**
     * Method isTimeMoreThanZeroMinAndLessThan10MinsOfResponseTimeout
     * Description
     *
     * @param responseTimeoutSeconds Integer
     *
     * @return boolean
     */
    private boolean isTimeMoreThanZeroMinAndLessThan10MinsOfResponseTimeout(Integer responseTimeoutSeconds) {
        return ( null != responseTimeoutSeconds ) && ( responseTimeoutSeconds.intValue() > 0 )
               && ( responseTimeoutSeconds.intValue() <= 600 );
    }

    /**
     * Method isTimeMoreThanZeroMinAndLessThan2MinsOfConnectionTimeout
     * Description
     *
     * @param connectionTimeoutSeconds Integer
     *
     * @return boolean
     */
    private boolean isTimeMoreThanZeroMinAndLessThan2MinsOfConnectionTimeout(Integer connectionTimeoutSeconds) {
        return ( null != connectionTimeoutSeconds ) && ( connectionTimeoutSeconds.intValue() > 0 )
               && ( connectionTimeoutSeconds.intValue() <= 120 );
    }

    /**
     * Method destory
     * Description
     *
     * @throws TTGHttpClientException
     */
    public static void destory() throws TTGHttpClientException {
        HttpClient.get().close();
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
